package com.ruicar.afs.cloud.afscase.processor.query;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkProcessScheduleInfo;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoTempService;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseChannelInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseChannelInfoService;
import com.ruicar.afs.cloud.afscase.processor.enums.QueryRoleType;
import com.ruicar.afs.cloud.afscase.processor.enums.WorkflowType;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.query.QueryCondition;
import com.ruicar.afs.cloud.common.core.security.vo.RoleVo;
import com.ruicar.afs.cloud.common.core.security.vo.UserVo;
import com.ruicar.afs.cloud.common.core.util.SpringContextHolder;
import com.ruicar.afs.cloud.seats.entity.UserCollocation;
import com.ruicar.afs.cloud.seats.service.UserCollocationService;
import com.ruicar.afs.cloud.seats.util.PostStatus;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.CommonGetRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.GetAssignUserRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.UserOnlineRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.response.*;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.WorkFlowResponse;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.response.FLowNodeUserBean;
import com.ruicar.afs.cloud.workflow.gwt.processor.AfsWorkFLowQueryProcessor;
import com.ruicar.afs.cloud.workflow.gwt.processor.DefaultAfsWorkFLowQueryProcessor;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @param
 * @Description 放款相关流程查询操作处理
 * @Author yk.Li
 * @Date 2020/7/30
 */
@Component
@AllArgsConstructor
@Slf4j
public class LoanQueryProcessor implements AfsWorkFLowQueryProcessor {
    UserCollocationService userCollocationService;
    WorkProcessScheduleInfoService workProcessScheduleInfoService;
    WorkProcessScheduleInfoTempService workProcessScheduleInfoTempService;
    CaseChannelInfoService caseChannelInfoService;
    CaseBaseInfoService caseBaseInfoService;
    WorkflowService workflowService;

    @Override
    public List<String> afsFLowKeys() {
        return Arrays.asList(new String[]{
                WorkflowType.LOAN_APPROVAL_NEW.getAfsFlowKey(),
                WorkflowType.LOAN_APPROVAL_OLD.getAfsFlowKey(),
                WorkflowType.LOAN_GPS_AUDIT.getAfsFlowKey()
        });
    }

    /**
     * 第一次分配到紫色节点  <在岗用户平均分配></>
     * @param userOnlineRequest user online request
     * @return
     */
    @Override
    public List<UserOnlineResponse> checkUserOnline(UserOnlineRequest userOnlineRequest) {
        return SpringContextHolder.getBean(NormalQueryProcessor.class).checkUserOnline(userOnlineRequest);
    }

    @Override
    public GetAssignUserResponse getAssignUser(GetAssignUserRequest getAssignUserRequest) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).getAssignUser(getAssignUserRequest);
    }

    @Override
    public QueryOrgConditionResponse queryOrgCondition(CommonGetRequest commonGetRequest) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).queryOrgCondition(commonGetRequest);
    }

    /**
     * @param
     * @Description 设计器获取角色类型<点击常规处理人节点中的选择类型触发此方法></>
     * @Author yk.Li
     * @Date 2020/7/31
     */
    @Override
    public QueryRoleResponse queryRole(CommonGetRequest commonGetRequest) {
        return SpringContextHolder.getBean(NormalQueryProcessor.class).queryRole(commonGetRequest);
    }

    /**
     * @param
     * @Description 设计器点击<从业务端选择人员></>触发
     * @Author yk.Li
     * @Date 2020/7/31
     */
    @Override
    public Page<QueryUserResponse> queryUserInfo(QueryCondition<Map<String, Object>> queryCondition) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).queryUserInfo(queryCondition);
    }

    /**
     * @param
     * @Description 第二次流转到该节点触发
     * @Author yk.Li
     * @Date 2020/7/31
     */
    @Override
    public UserVo getRtnUserInfo(CommonGetRequest commonGetRequest) {
        log.info("回退人员获取 ==> {}", commonGetRequest);
        WorkProcessScheduleInfo info = workProcessScheduleInfoService.getById(commonGetRequest.getBizDataId());
        CaseChannelInfo channelInfo = caseChannelInfoService.getOne(
                Wrappers.<CaseChannelInfo>lambdaQuery().eq(CaseChannelInfo::getApplyNo, info.getApplyNo())
        );
        String loginName = "auto";
        String userRealName = "流程自动节点默认用户";
        UserVo userVo = new UserVo();
        if(loginName.equals(commonGetRequest.getBodyData())){
            userVo.setUsername(loginName);
            userVo.setUserRealName(userRealName);
        }else {
            UserCollocation user = checkOnline(commonGetRequest.getBodyData(),info);
            userVo.setUsername(Convert.toStr(channelInfo.getId(), "").equals(commonGetRequest.getBodyData())
                    ? Convert.toStr(channelInfo.getId())
                    : user.getLoginName());
            userVo.setUserRealName(Convert.toStr(channelInfo.getId(), "").equals(commonGetRequest.getBodyData())
                    ? channelInfo.getDealerName()
                    : user.getUserRealName());
        }
        log.info("回退人员响应 ==> {},{}", userVo.getUsername(), userVo.getUserRealName());
        return userVo;
    }

    /**
     * @Description 检查是否在岗
     * @Author yk.Li
     * @Date 2020/08/11
     */
    private UserCollocation checkOnline(String userName,WorkProcessScheduleInfo info) {
        UserCollocation userCollocation = userCollocationService.getOne(
                Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, userName)
        );
        // 存在员工用户名
        if (Objects.nonNull(userCollocation)) {
            if (Objects.nonNull(userCollocation) && !PostStatus.YES.getCode().equals(userCollocation.getPostStatus())) {
                if (StrUtil.isNotBlank(userCollocation.getAgentLoginName())) {
                    UserCollocation agentCollocation = userCollocationService.getOne(
                            Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, userCollocation.getAgentLoginName())
                    );
                    if (Objects.nonNull(agentCollocation) && PostStatus.YES.getCode().equals(agentCollocation.getPostStatus())) {
                        userCollocation = agentCollocation;
                    }else {
                        userCollocation= getUsableUser(userCollocation ,info);
                    }
                }else{
                    userCollocation= getUsableUser(userCollocation ,info);
                }
            }
        }
        return userCollocation;
    }

    /**
     * @param
     * @Description 经销商信息获取
     * @Author yk.Li
     * @Date 2020/7/31
     */
    @Override
    public UserVo getApplyUserInfo(CommonGetRequest commonGetRequest) {
        return SpringContextHolder.getBean(NormalQueryProcessor.class).getApplyUserInfo(commonGetRequest);
    }

    /**
     * @param
     * @Description 获取代理组长信息 根据在岗状态分配人员
     * @Author yk.Li
     * @Date 2020/7/30
     */
    @Override
    public UserVo getLeader(CommonGetRequest commonGetRequest) {
        log.info("代理组长信息获取 ==> {}", commonGetRequest);
        //获取原处理人信息
        UserCollocation userCollocation = userCollocationService.getOne(
                Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, commonGetRequest.getBodyData())
        );
        // 上一节点处理人登录名，没有配置坐席则直接返回上一岗位处理人
        String userName = Convert.toStr(commonGetRequest.getBodyData());
        if (Objects.nonNull(userCollocation)) {
            //获取代理组长
            String leaderLoginName = userCollocation.getAgentGroupLeaderLoginName();
            if (StrUtil.isNotBlank(leaderLoginName)) {
                //代理组长在不在岗均分配给代理组长
                userName = leaderLoginName;
            }
        }
        UserVo userVo = new UserVo();
        userVo.setUsername(userName);
        log.info("代理组长信息响应 ==> {}", userName);
        return userVo;
    }


    /**
     * @param commonGetRequest
     * @Description 获取指定处理人
     * @Author yk.Li
     * @Date 2020/7/30
     */
    @Override
    public UserVo getOperUser(CommonGetRequest commonGetRequest) {
        return SpringContextHolder.getBean(NormalQueryProcessor.class).getOperUser(commonGetRequest);
    }

    /**
     * @Description 普通节点选择人员原路返回
     * @Author yk.Li
     * @Date 2020/7/30
     * @param commonGetRequest common get request
     */
    @Override
    public List<UserVo> commonNodeCheckUser(CommonGetRequest commonGetRequest) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).commonNodeCheckUser(commonGetRequest);
    }

    /**
     * 紫色节点-通过当前节点ID获取当前节点下所有成员并获取可用的用户
     */
    public UserCollocation getUsableUser(UserCollocation self,WorkProcessScheduleInfo info){
        UserCollocation userCollocation=new UserCollocation();
        List<UserCollocation> usableUsers=new ArrayList<>();
        if(!ObjectUtils.isEmpty(info)){
            try {
                WorkFlowResponse<Page<FLowNodeUserBean>> workFlowResponse = workflowService.queryNodeUser(info.getCurrentNodeId(), 1, 10000);
                List<FLowNodeUserBean> list = workFlowResponse.getAfsData().getRecords();
                if(list.size()>0) {
                    list.forEach(bean -> {
                        UserCollocation user = userCollocationService.getOne(Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, bean.getUserName()));
                        int weight = bean.getWeight() - bean.getTaskCount();
                        if (user.getPostStatus().equals(PostStatus.YES.getCode())) {
                            user.setUsableCount(weight);
                            usableUsers.add(user);
                        }
                    });
                }
            }catch (Exception e){
                log.error("{},{}=>调用操作组人员接口失败",info.getCurrentNodeId(),info.getCurrentNodeName());
            }
        }
        if(usableUsers.size()>0){
            usableUsers.stream().sorted(Comparator.comparing(UserCollocation::getUsableCount).reversed()).sorted(Comparator.comparing(UserCollocation::getLoginName));
            userCollocation=usableUsers.get(0);
        }else{
            userCollocation=self;
        }
        return userCollocation;
    }
}
